'use strict';

module.exports = core;

const semver = require('semver');
const path = require('path');
const colors = require('colors');
const userHome = require('user-home');
const pathExists = require('path-exists').sync;
const commander = require('commander');

const pkg = require('../package.json');
const log = require('@dmj-cli/log');
const exec = require('@dmj-cli/exec');
const constant = require('./const');

const program = new commander.Command();

async function core() {
    try {
        await prepare();
        registerCommand();
    } catch (error) {
        log.error(error.message);
        if (program.debug) {
            console.log(e);
        }
    }
}

async function prepare() {
    checkPkgVersion();
    checkRoot();
    checkUserHome();
    checkEnv();
    await checkGlobalUpdate();
}

// 检查版本号
function checkPkgVersion() {
    log.notice('cli', pkg.version);
}

// 检查root账户  root-check 会自动降级
function checkRoot() {
    const rootCheck = require('root-check');
    rootCheck();
}

// 检查用户目录是否存在
function checkUserHome() {
    if (!userHome || !pathExists(userHome)) {
        throw new Error(colors.red('当前登录的用户主目录不存在!'));
    }
}

// 检查环境变量
function checkEnv() {
    const dotebv = require('dotenv');
    const dotenvPath = path.resolve(userHome, '.env')
    if (pathExists(dotenvPath)) {
        dotebv.config({
            path: dotenvPath
        });
    }
    createDefaultConfig();
}

function createDefaultConfig() {
    const cliConfig = {
        home: userHome
    };
    if (process.env.CLI_HOME) {
        cliConfig['cliHome'] = path.join(userHome, process.env.CLI_HOME);
    } else {
        cliConfig['cliHome'] = path.join(userHome, constant.DEFAULT_CLI_HOME);
    }
    process.env.CLI_HOME_PATH = cliConfig.cliHome;
}

async function checkGlobalUpdate() {
    // 1、获取当前的版本号和模块名
    const currentVersion = pkg.version;
    const npmName = pkg.name;
    // 2、调用npm api获取所有版本号
    const {
        getNpmSemverVersion
    } = require('@dmj-cli/get-npm-info');
    // 3、提取所有版本号，比对哪些版本号是大于当前版本号
    const lastVersion = await getNpmSemverVersion(currentVersion, npmName);
    // 4、获取最新的版本号，提示用户更新到该版本
    if (lastVersion && semver.gt(lastVersion, currentVersion)) {
        log.warn('更新提示', colors.yellow(`请手动更新 ${npmName}, 当前版本: ${currentVersion}, 最新版本: ${lastVersion}
        更新命令: npm install -g ${npmName}`));
    }
}

// 注册命令
function registerCommand() {
    // 注册版本号
    program
        .name(Object.keys(pkg.bin)[0])
        .usage('<command> [options]')
        .version(pkg.version)
        .option('-d, --debug', '是否开启调试模式', false)
        .option('-tp, --targetPath <targetPath>', '是否指定本地调试文件路径', '');


    // 注册初始化项目命令
    program
        .command('init [projectName]')
        .option('-f, --force', '是否强制初始化项目')
        .action(exec);

    // 开启debug模式
    program.on('option:debug', function () {
        // 获取命令的所有参数 是一个对象
        const options = program.opts();
        if (options.debug) {
            process.env.LOG_LEVEL = 'verbose';
        } else {
            process.env.LOG_LEVEL = 'info';
        }
        log.level = process.env.LOG_LEVEL;
    });

    // 指定targetPath 通过环境变量  进行传递 解耦合
    program.on('option:targetPath', function () {
        process.env.CLI_TARGET_PATH = program.opts().targetPath
    })

    // 对未知命令的监听
    program.on('command:*', function (obj) {
        const availableCommands = program.commands.map(cmd => cmd.name());
        console.log(colors.red('未知命令:' + obj[0]));
        if (availableCommands.length > 0) {
            console.log(colors.red('可用命令:' + availableCommands.join(',')));
        }
    });

    // 传入参数解析
    program.parse(process.argv);

    // 当没有输入参数时打印帮助文档
    if (program.args && program.args.length < 1) {
        // 输出帮助文档
        program.outputHelp();
        console.log();
    }
}